﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MadProps
{
    static class PropFactory
    {
        internal static T BuildSchema<T>()
        {
            T obj = (T)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(T));
            CreatePropsFor(obj, null);
            return obj;
        }

        internal static void CreatePropsFor(object obj, ICollection<IProp> collector)
        {
            foreach (var propId in PropIdCache.GetPropIds(obj.GetType()))
            {
                var member = propId.ClrMember;

                // TODO should actually get the IProp<T> interface and see what
                // type closes the "T" parameter
                var propType = member.Type.GetGenericArguments().SingleOrDefault();
                if (propType == null)
                {
                    throw new Exception(string.Format(
                        "Prop type cannot be determined because {0}.{1} is not declared as IProp<T>",
                        member.DeclaringType.Name, member.Name));
                }

                var type = typeof(Prop<>).MakeGenericType(propType);
                var prop = Activator.CreateInstance(type, propId, obj) as IProp;
                member.SetValue(obj, prop);

                if (collector != null)
                {
                    collector.Add(prop);
                }
            }
        }
    }
}
